iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 12
1
Modern Web

JavaScript 之旅系列 第 12

JavaScript 之旅 (12):RegExp Lookbehind Assertions

  • 分享至 

  • xImage
  •  

本篇介紹 ES2018 (ES9) 提供的 RegExp Lookbehind Assertions。

Lookarounds 是 zero-width assertions,該 assertion 與字串 match 而 consuming 任何內容。

過去 ECMAScript 有 lookahead assertions 的向前 assertions,但沒有 lookbehind assertions 提供的向後 assertions。

lookbehind assertions 分為 positive 和 negative。使用 lookbehind assertions 可以確保某個 pattern 之前有或沒有另一個 pattern,例如:可以 match 美元金額,但不 capture 美元符號。

Positive Lookbehind Assertions:(?<=...)

(?<=x)y 代表 x 後面若接著 y 時,才會 match y

可確保其中包含的 pattern 位於 assertion 之後的 pattern 之前

例如:match 美元金額而不 capture 美元符號:

let pattern = /(?<=\$)\d+(\.\d*)?/;

let match1 = pattern.exec('$59.21');
console.log(match1);
// ["59.21", ".21", index: 1, input: "$59.21", groups: undefined]

let match2 = pattern.exec('€59.21');
console.log(match2);
// null

Negative Lookbehind Assertions:(?<!...)

(?<=x)y 代表 x 後面不是接著 y 時,才會 match y

確保其中的 pattern 不位於 assertion 之後的 pattern 之前

例如:不會 match 美元金額,但會 match 歐元金額:

let pattern = /(?<!\$)\d+(?:\.\d*)/;

let match1 = pattern.exec('$9.87');
console.log(match1);
// null

let match2 = pattern.exec('€9.87');
console.log(match2);
// ["9.87", index: 1, input: "€9.87", groups: undefined]

所有 RegExp pattern,甚至是 unbounded pattern 都可作為 lookbehind assertions 的一部分。例如:可用 /(?<=\$\d+\.)\d+/ 來 match 美元金額並只 capture 小數部份:

let pattern = /(?<=\$\d+\.)\d+/;

let match = pattern.exec('$59.21');
console.log(match);
// ["21", index: 4, input: "$59.21", groups: undefined]

pattern 通常從最左邊的 sub-pattern 開始 match,若左邊的 sub-pattern match 成功,就會繼續移動至右邊的 sub-pattern。當包含在 lookbehind assertion 中時,match 順序會相反。pattern 會從最右邊的 sub-pattern 開始 match,然後向左取代。

例如:/(?<=\$\d+\.)\d+/ pattern 會先找到一個數字,並確定後面接著 .,然後 \d+. 開始的,最後 $ 從 assertion 中的 \d+ 位置開始。所以回溯 (backtracking) 的方向也會相反。

資料來源


上一篇
JavaScript 之旅 (11):RegExp Unicode property escapes
下一篇
JavaScript 之旅 (13):Object Rest/Spread Properties
系列文
JavaScript 之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言